package com.java.collection.concurrent;

import java.util.*;
import java.util.concurrent.*;

/**
 *   fast-fail事件产生的条件：
 *   当多个线程对Collection进行操作时，若在线程A通过iterator去遍历集合时，该集合的内容被其他线程所改变，则线程A遍历过程中会抛出ConcurrentModificationException异常。
 *   fast-fail解决办法：使用util.concurrent包下的相关类应对多线程操作集合的情况。
 *
 *   (01) 使用ArrayList时，会产生fast-fail事件，抛出ConcurrentModificationException异常；定义如下：
 *            private static List<String> list = new ArrayList<String>();
 *   (02) 使用时CopyOnWriteArrayList，不会产生fast-fail事件；定义如下：
 *            private static List<String> list = new CopyOnWriteArrayList<String>();
 */

public class FailFast {

    //private static List<String> list = new ArrayList<String>();
    private static List<String> list = new CopyOnWriteArrayList<String>();
    
    public static void main(String[] args) {
        new ThreadA("THREAD-A").start();
        new ThreadB("THREAD-B").start();
    }
    private static synchronized void printAll() {
        System.out.println("----"+Thread.currentThread().getName());
        Iterator<String> iter = list.iterator();
        while(iter.hasNext()) {
        	try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
            System.out.print(iter.next()+", ");
        }
    }
    //向list中依次添加0,1,2,3,4,5，每添加一个数之后，就通过printAll()遍历整个list
    private static class ThreadA extends Thread {
    	public ThreadA(String name){
    		super(name);
    	}
        public void run() {
            int i = 0;
            while (i<6) {
                list.add(String.valueOf(i));
                printAll();
                i++;
            }
        }
    }
    //在线程A开始遍历后线程B修改列表
    private static class ThreadB extends Thread {
    	public ThreadB(String name){
    		super(name);
    	}
        public void run() {
        	try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			list.add("999");
        }
    }
}